<?php
/*********************************************
 *  CPG Dragonfly™ CMS
 *********************************************
	Copyright © since 2010 by CPG-Nuke Dev Team
	http://dragonflycms.org

	Dragonfly is released under the terms and conditions
	of the GNU GPL version 2 or any later version
*/

namespace Poodle\Kernels;

class JavaScript extends PushFiles
{
	protected
		$f_ext = '.js',
		$mime  = 'application/x-javascript',

		$cfg   = array(
			'cache_dir'   => null,
			'cache_uri'   => null,
			'design_mode' => false,
			'expires'     => 8035200, // 3 months
		);

	function __construct(array $cfg, $path='')
	{
		$keys = $path ? $path : \Poodle::$PATH;
		if (2!=count($keys)
		 || !preg_match('#^([a-z0-9_\-]+(;|$))+$#D', $keys[1])
		) {
			\Poodle\HTTP\Headers::setStatus(412);
			exit(\Poodle\HTTP\Status::get(412));
		}

		parent::__construct($cfg);

		$files = $this->getValidFilesList($keys[1]);

		// Make poodle.js the main priority
		if (isset($files['poodle'])) {
			$f = $files['poodle'];
			unset($files['poodle']);
			if (!stripos($_SERVER['HTTP_USER_AGENT'],'Trident/') && preg_match('#compatible; MSIE [67]#',$_SERVER['HTTP_USER_AGENT'])) {
				$f = $this->findFile('poodle_poodle-ie7');
			} else if (stripos($_SERVER['HTTP_USER_AGENT'],'Trident/4.0')) {
				$f = $this->findFile('poodle_poodle-ie8');
			}
			if (preg_match('#compatible; MSIE [6789]#',$_SERVER['HTTP_USER_AGENT'])) {
				// Simulate HTML5 Drag&Drop in IE < 10
				array_unshift($files, $this->findFile('poodle_dragndrop-ie9'));
			}
			array_unshift($files, $f);
		}
		// filter out the missing files
		$files = array_filter($files);

		if (!$this->cfg['expires'] || $this->cfg['design_mode']) {
			$this->cfg['expires'] = 0;
			foreach ($files as $file) { $this->mtime = max($this->mtime, @filemtime($file)); }
		}

		$etag_files = $files;
		ksort($etag_files);
		$this->ETag  = md5(implode(';', $etag_files)) . (self::$DEBUG&self::DBG_JAVASCRIPT?'-1':'-0') . ($this->cfg['design_mode']?'-1':'-0');
		$this->CFile = 'javascript/'.$this->ETag;

		$this->files = $files;
	}

	protected function findFile($filename)
	{
		$ext  = $this->f_ext;
		$dirs = array(self::$DIR_BASE.'inc/js');
		if ($file = \Poodle::getFile($filename.$ext, $dirs)) { return $file; }
		else {
			$path = explode('_', $filename);
			$lib  = array_shift($path); // library
			$comp = $path ? array_shift($path) : $lib; // component
			if (empty($path[0])) $path[0] = $comp;
			if (($file = \Poodle::getFile("{$lib}/{$comp}/tpl/".implode('/',$path).$ext))
			 || ($file = \Poodle::getFile("{$lib}/javascript/{$comp}".($path[0]!=$comp?'_'.implode('_',$path):'').$ext)))
			{
				return $file;
			}
//			else if ($file = \Poodle::getFile($comp.($path[0]!=$comp?'_'.implode('_',$path):'').$ext, array(self::$DIR_BASE."tpl/{$lib}/js")) { return $file; }
		}
		return false;
	}

	protected function findL10NFile($filename)
	{
		$ext  = '.'.$this->lng.$this->f_ext;
		$dirs = array(self::$DIR_BASE.'inc/js');
		if ($file = \Poodle::getFile($filename.$ext, $dirs)) { return $file; }
		else {
			$path = explode('_', $filename);
			$lib  = array_shift($path); // library
			$comp = $path ? array_shift($path) : $lib; // component
			if (!isset($path[0])) $path[0] = $comp;
			if ($file = \Poodle::getFile("{$lib}/{$comp}/l10n/".(isset($path[0])?implode('/',$path):$comp).$ext)) { return $file; }
			else if ($file = \Poodle::getFile("{$lib}/javascript/l10n/{$comp}".($path[0]!=$comp?'_'.implode('_',$path):'').$ext)) { return $file; }
//			else if ($file = \Poodle::getFile($comp.($path[0]!=$comp?'_'.implode('_',$path):'').$ext, array(self::$DIR_BASE."tpl/{$lib}/js")) { return $file; }
		}
		return false;
	}

	public function run()
	{
		$this->send_file();

		# http://blog.stevenlevithan.com/archives/match-quoted-string speed?
//		$str_re = '#(["\'])(?:.*[^\\\\]+)*(?:(?:\\\\{2})*)+\1#xU';
//		$str_re = '#(["\'])(?:\\\\?[^\n])*?\1#s';
		$str_re = '#"[^\n"\\\\]*(?:\\\\.[^\n"\\\\]*)*"|\'[^\n\'\\\\]*(?:\\\\.[^\n\'\\\\]*)*\'|/[^\s/\\\\]+(?:\\\\.[^\n/\\\\]*)*/[gmi]*#';

		# file didn't exist yet, failed or needs updating
		$data = "/* CPG Dragonfly™ CMS, Copyright © since 2010 by CPG-Nuke Dev Team. All rights reserved. */\n";
		if ($this->missing) { $data .= "/* Not found:\n\t".implode("\n\t",$this->missing)."\n*/\n"; }
		if (self::$DEBUG & self::DBG_JAVASCRIPT) { $data .= "/* Found:\n\t".implode("\n\t",$this->files)."\n*/\n"; }
		foreach ($this->files as $file)
		{
			$buffer = file_get_contents($file);
			if ($buffer)
			{
				$buffer = str_replace("\r", '', $buffer);
				$buffer = preg_replace('#(^|\s+)//.*#m', '', $buffer);
				$buffer = preg_replace('#(^|\s+)/\*[^@].*?\*/#s', '', $buffer); // Strip comments but keep IE specific stuff
				if (!(self::$DEBUG & self::DBG_JAVASCRIPT)) {
					$buffer = preg_replace('#console\.[a-z]+\(((?(?!\);).)*)\);#', '', $buffer);
				}
				if (!$this->cfg['design_mode']) {
					preg_match_all($str_re, $buffer, $strings);
					$strings = $strings[0];
					$buffer = preg_split($str_re, $buffer);
//					$buffer = str_replace("\n", '', $buffer);
					$buffer = preg_replace('#\n+#', ' ', $buffer);
					$buffer = preg_replace('#\s+#', ' ', $buffer);
					# case|else if|function|in|new|return|typeof|var
					$buffer = preg_replace('#\s*([&%/\[\]{}\(\)\|\+!\?\-=:;,><\.\*]+)\s*#', '$1', $buffer);
//					$buffer = preg_replace('#\s*(\$?[^a-z_])\s*#si', '$1', $buffer);
					$buffer = str_replace(';}', '}', $buffer);
					$c = 1;
					while ($c) { $buffer = preg_replace('#var([^;]+);var#', 'var$1,', $buffer, -1, $c); }
					$c = count($strings);
					for ($i = 0; $i < $c; ++$i) { $buffer[$i] .= $strings[$i]; }
					$data .= implode('', $buffer);
				} else {
					$buffer = preg_replace('#[ \t]+#s', ' ', $buffer);
					$data .= preg_replace('#(\n)\s+#s', '$1', $buffer);
				}
				$buffer = '';
			}
		}

//		echo $data;
//		print_r($this);
//		exit;
		$this->send_file($data);
	}

}
